/*
 * Copyright (c) 2024, Qi Yaolong.
 * dragon@hbu.edu.cn
 * HeBei University, China.
 * 
 * 简体中文
 * 保留所有权利。依据GPL 2.0（以下简称"本许可"）进行许可。除非符合（遵守）本许可及以下条款，否则
 * 您不得使用此文件：
 * 
 * 禁止任何未经授权的个人或组织以任何形式将本程序及其附属资料、创新、创意、架构设计、算法、衍生作品
 * 等用于任何商业目的、盈利活动、各类竞赛(比赛)、直播教学、录播教学、线下课程、书籍编写、教材编写、
 * 会议、培训、公益活动、项目课题、毕业设计、毕业论文、学术论文等。
 * 
 * 本程序由版权持有人和贡献人“按原样”提供，不提供任何明示或暗示担保，包括但不局限于对适销性和特定
 * 用途适合性的暗示担保。在任何情况下，版权持有人或贡献人对因使用本程序而导致的任何直接、间接、附带、
 * 特殊、典型或后果性损害（包括但不限于购买替代商品或服务；使用损失、数据丢失或利润损失；业务中断）
 * 不承担任何责任，无论其如何产生，也不论其责任理论为何，无论是合同、严格责任还是侵权（包括疏忽或
 * 其他），即使已告知此类损害的可能性。
 * 
 * English
 * All rights reserved. Licensed under the GPL 2.0 (the "License"). You may NOT 
 * use this file except in compliance with the License and the following terms:
 * 
 * IT IS PROHIBITED FOR ANY UNAUTHORIZED PERSON OR ENTITY TO USE THIS PROGRAM AND 
 * ITS ANCILLARY DATA, INNOVATIONS, CONCEPTS, ARCHITECTURE DESIGN, ALGORITHMS, 
 * DERIVED WORKS, ETC., IN ANY FORM FOR COMMERCIAL PURPOSES, PROFIT-MAKING 
 * ACTIVITIES, VARIOUS COMPETITIONS (CONTESTS), LIVE TEACHING, PRE-RECORDED 
 * LESSONS, OFFLINE COURSES, BOOK WRITING, CONFERENCES, TRAININGS, PUBLIC WELFARE 
 * ACTIVITIES, PROJECTS, TOPICS, GRADUATION DESIGNS, DISSERTATIONS, THESES, AND 
 * OTHER APPLICATIONS.
 * 
 * THIS PROGRAM IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS PROGRAM, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// UART2自收自发
// 测试方法：
// 短接UART2的RX（GPIO07）和TX（GPIO08）引脚，形成自收自发，观察数据是否正常收发

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "iot_uart.h"
#include "pinctrl.h"
#include "uart.h"
#include "drv_uart.h"
#include "common.h"

// ==============================================================================
// ==============================================================================
// ==============================================================================

static _UartPkgsInfo_ mUartPkgs;


// 接收数据的回调函数
// UART2的RX引脚收到数据后，将数据发送到UART2的TX引脚（从UART2的TX引脚发出数据）
// 可以短接UART2的RX（GPIO07）和TX（GPIO08）引脚，形成自收自发，观察数据是否正常收发
static void uart2_rx_callback(const void *buffer, uint16_t length, bool error)
{
    // osal_printk("uart2_rx_callback: %s\n", (const char *)buffer);
    // IoTUartWrite(UART2, (const unsigned char *)buffer, (uint32_t)length);
    // uapi_watchdog_kick(); // 踢狗，防止CPU占用过高导致看门狗复位

    Debug_DataBuff("RX-", buffer, length);
}

// 配置UART2
void uart2_config(void)
{
    osal_printk("\r[long] uart config \n");
    uapi_uart_deinit(UART2);

    osal_printk("\r[long] uart IoTUartInit \n");
    IotUartAttribute g_uart_cfg = {115200, 8, 1, IOT_UART_PARITY_NONE, 100, 100, 0};
    IoTUartInit(UART2, &g_uart_cfg);
    // 注册回调函数。在接收回调处理过程中接收到的UART数据，会直接丢弃
    // UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE:
    // 如果接收缓存已满，或者接收的数据量到达指定的数据长度，或者接收数据暂停，就触发数据接收回调
    osal_printk("\r[long] uart Callback reg \n");
    (void)uapi_uart_register_rx_callback(UART2, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, 16, uart2_rx_callback);
}

/**
 * @brief 
 * 
 */
void initUartTxDataBuffer(void)
{
    memset(mUartPkgs.uartTxBuffer, 0, sizeof(mUartPkgs.uartTxBuffer));
}

/**
 * @brief 
 * 
 */
void updateUartTxDataBuffer(void)
{
    static uint32_t cnt_TxTime = 0;

    mUartPkgs.uartTxBuffer[0] = 0x01;
    mUartPkgs.uartTxBuffer[1] = 0x03;

    mUartPkgs.uartTxBuffer[2] = 0x00;
    mUartPkgs.uartTxBuffer[3] = 0xFF & cnt_TxTime;

    mUartPkgs.uartTxBuffer[4] = 0x00;
    mUartPkgs.uartTxBuffer[5] = 0x01;

    mUartPkgs.lenTx = 6;

    cnt_TxTime ++;
    cnt_TxTime = cnt_TxTime % 0xF0;
}

// 主线程函数
static void UartTask(void)
{
    osal_printk("\r------------------------------ main Uart Task ------------------------------ \n");
    // uapi_watchdog_disable(); // 关闭看门狗
    uart2_config(); // 配置UART2
    initUartTxDataBuffer();

    while (1)
    {
        updateUartTxDataBuffer();
        Debug_DataBuff("TX-", mUartPkgs.uartTxBuffer, mUartPkgs.lenTx);
        IoTUartWrite(UART2, mUartPkgs.uartTxBuffer, mUartPkgs.lenTx);
        osDelay(100);  // delay time
    }
    
}

// 入口函数
void UartEntry(void)
{
    osThreadAttr_t attr = {0};
    attr.name = "Uart Task";
    attr.stack_size = 1024 * 2;
    attr.priority = osPriorityNormal;
    
    if (osThreadNew(UartTask, NULL, &attr) == NULL)
    {
        osal_printk("[UartEntry] Falied to create UartTask ...\n");
    }
}

// 运行入口函数
// APP_FEATURE_INIT(UartEntry);
